package com.lq.dao;

import com.alibaba.fastjson.JSONObject;
import com.lq.common.Constants;
import com.lq.common.SqlConstant;
import com.lq.utils.jdbc.Jdbc;
import com.lq.utils.jdbc.LqJdbcFactory;
import com.lq.utils.jdbc.LqPiLiang;
import org.apache.commons.collections.map.ListOrderedMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

public class MultiThreadPoint extends Thread {

    public static Logger logDevice = Logger.getLogger("device");
    private String terraceType;
    private List<ListOrderedMap> companyList;
    private List<Object> subList;
    private CountDownLatch countDownLatch;

    public void setTerraceType(String terraceType) {
        this.terraceType = terraceType;
    }

    public void setCompanyList(List<ListOrderedMap> companyList) {
        this.companyList = companyList;
    }

    public void setSubList(List<Object> subList) {
        this.subList = subList;
    }

    public void setCountDownLatch(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
        try {
            int result = 0;
            List<Object[]> objectList1 = new ArrayList<>();
            List<Object[]> objectList2 = new ArrayList<>();
            logDevice.info("Thread " + Thread.currentThread().getName() + " is processing  dataSize" + subList.size());

            //将企业编号和库区编号放到Map中进行下面判断处理
            Map<String, String> companyAreaMap = new HashMap<>();
            if(Constants.TERRACE_TYPE.equals(terraceType) && companyList != null){
                companyList.stream().forEach(company -> {
                    String companyCode = company.get("company_code") != null ? company.get("company_code").toString() : "";
                    String areaCode = company.get("area_code") != null ? company.get("area_code").toString() : "";
                    String key = companyCode + "_" + areaCode;
                    companyAreaMap.put(key, companyCode);
                });
            }
            for (int i = 0; i < subList.size(); i++) {
                JSONObject pointJson = JSONObject.parseObject(subList.get(i).toString());

                String deviceIdInside = pointJson.get("sn").toString();
                String companyCode = pointJson.get("company_code").toString();
                String areaCode = pointJson.get("area_code").toString();
                //私有化平台的话才进行判断
                if(Constants.TERRACE_TYPE.equals(terraceType)){
                    String key = companyCode + "_" + areaCode;
                    if(!companyAreaMap.containsKey(key)){
                        continue; //如果不存在则跳过，不添加到Object中
                    }
                }
                String deviceHostId = pointJson.get("host_sn").toString();
                String deviceId = pointJson.get("sn_show").toString();
                String pointAddr = pointJson.get("point_addr").toString();
                String pointName = pointJson.get("point_name").toString();
                String storehouseProperty = pointJson.get("storehouse_property").toString();
                String displayType = pointJson.get("display_type").toString();
                String saveType = StringUtils.isNotBlank(displayType) && !"null".equals(displayType) ? displayType : "1";

                String isDeviceEmpty = pointJson.get("is_device_empty").toString();
                String deviceEmpty = StringUtils.isNotBlank(isDeviceEmpty) && !"null".equals(isDeviceEmpty) ? isDeviceEmpty : "0";
                String emptyState = pointJson.get("empty_state").toString();
                String hostEquipmentNumber = pointJson.containsKey("equipment_number") ? pointJson.getString("equipment_number") : "";
                Integer serialNumber = pointJson.containsKey("serial_number") ? pointJson.getInteger("serial_number") : 0;
                //监测类型
                String monitoringType = pointJson.get("monitoring_type").toString();
                //校准到期时间
                String expirationTime = pointJson.get("expiration_time") + "";
                //坐标X轴
                String x = pointJson.get("x") + "";
                //坐标Y轴
                String y = pointJson.get("y") + "";
                //温度报警上限
                String temAHL = pointJson.get("tem_alarm_high_limit") + "";
                String temAlarmHighLimit = StringUtils.isNotBlank(temAHL) && !"null".equals(temAHL) ? temAHL : null;
                //温度报警下限
                String temALL = pointJson.get("tem_alarm_lower_limit") + "";
                String temAlarmLowerLimit = StringUtils.isNotBlank(temALL) && !"null".equals(temALL) ? temALL : null;
                //温度预警上限
                String temWHL = pointJson.get("tem_warning_high_limit") + "";
                String temWarningHighLimit = StringUtils.isNotBlank(temWHL) && !"null".equals(temWHL) ? temWHL : null;
                //温度预警下限
                String temWLL = pointJson.get("tem_warning_lower_limit") + "";
                String temWarningLowerLimit = StringUtils.isNotBlank(temWLL) && !"null".equals(temWLL) ? temWLL : null;
                //湿度报警上限
                String humAHL = pointJson.get("hum_alarm_high_limit") + "";
                String humAlarmHighLimit = StringUtils.isNotBlank(humAHL) && !"null".equals(humAHL) ? humAHL : null;
                //湿度报警下限
                String humALL = pointJson.get("hum_alarm_lower_limit") + "";
                String humAlarmLowerLimit = StringUtils.isNotBlank(humALL) && !"null".equals(humALL) ? humALL : null;
                //湿度预警上限
                String humWHL = pointJson.get("hum_warning_high_limit") + "";
                String humWarningHighLimit = StringUtils.isNotBlank(humWHL) && !"null".equals(humWHL) ? humWHL : null;
                //湿度预警下限
                String humWLL = pointJson.get("hum_warning_lower_limit") + "";
                String humWarningLowerLimit = StringUtils.isNotBlank(humWLL) && !"null".equals(humWLL) ? humWLL : null;
                boolean contains = Arrays.stream(Constants.equipmentNumberArray).anyMatch(hostEquipmentNumber::equals);
                String extendSn = "";
                if (contains) {
                    extendSn = deviceHostId;
                } else {
                    extendSn = deviceId;
                }
                Object[] obj1 = new Object[]{
                        companyCode,
                        areaCode,
                        deviceId,
                        deviceIdInside,
                        deviceHostId,
                        pointAddr,
                        pointName,
                        storehouseProperty,
                        monitoringType,
                        hostEquipmentNumber,
                        serialNumber,
                        saveType,
                        emptyState,
                        x,
                        y,
                        temAlarmHighLimit, temAlarmLowerLimit, temWarningHighLimit, temWarningLowerLimit,
                        humAlarmHighLimit, humAlarmLowerLimit, humWarningHighLimit, humWarningLowerLimit,
                        deviceHostId,
                        extendSn,

                        companyCode,
                        areaCode,
                        deviceId,
                        deviceIdInside,
                        deviceHostId,
                        pointAddr,
                        pointName,
                        storehouseProperty,
                        monitoringType,
                        hostEquipmentNumber,
                        serialNumber,
                        saveType,
                        emptyState,
                        x,
                        y,
                        temAlarmHighLimit, temAlarmLowerLimit, temWarningHighLimit, temWarningLowerLimit,
                        humAlarmHighLimit, humAlarmLowerLimit, humWarningHighLimit, humWarningLowerLimit,
                        deviceHostId,
                        extendSn
                };
                objectList1.add(obj1);
                if (StringUtils.isNotBlank(expirationTime) && !"null".equals(expirationTime)) {
                    Object[] obj2 = new Object[]{
                            companyCode,
                            areaCode,
                            pointAddr,
                            deviceIdInside,
                            deviceHostId,
                            "measure_point_config_mqtt",
                            expirationTime
                    };
                    objectList2.add(obj2);
                }
            }
            //设备信息数据
            int[] piliangResult = Jdbc.piliang(SqlConstant.SQL_INSER_INTO_MEASURE_MQTT, new LqPiLiang() {
                public void piliang(LqJdbcFactory jdbc) {
                    objectList1.forEach(l -> {
                        jdbc.executeS(l);
                    });
                }
            });
            //校准到期时间信息数据
            Jdbc.piliang(SqlConstant.SQL_INSER_INTO_MEASURE_CALIBRATION_MQTT, new LqPiLiang() {
                public void piliang(LqJdbcFactory jdbc) {
                    objectList2.forEach(l -> {
                        jdbc.executeS(l);
                    });
                }
            });
            if (piliangResult != null) {
                result = 1;
            }
            logDevice.info("==========================================测点数据：" + (result > 0 ? "成功" : "失败") + " ======================================");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (countDownLatch != null) {
                countDownLatch.countDown();
            }
        }
    }
}
